<template>
  <el-upload
    ref="uploadImageRef"
    class="image-uploader"
    name="image"
    :action="uploadUrl"
    :headers="headers"
    :show-file-list="false"
    :on-error="handleError"
    :on-success="handleSuccess"
    :on-progress="handleOnProgress"
    :before-upload="beforeUpload"
  >
    <img v-if="imageUrl !== ''" :src="imageUrl" class="image-preview" :style="iconStyle" />
    <div v-else :style="iconStyle">
      <i :class="iconClass" class="wh-20px color-info"></i>
    </div>
  </el-upload>
</template>

<script setup lang="ts">
  import type { UploadInstance, UploadProps } from 'element-plus'

  import type { CSSProperties } from 'vue'

  import { getToken } from '#/utils/auth'
  import { ElMessage } from 'element-plus'

  defineOptions({
    name: 'UploadImage',
  })

  const props = withDefaults(
    defineProps<{
      field: string // 字段名
      height?: number
      isCreate: boolean
      preview: string
      upload: string
      width?: number
    }>(),
    {
      width: 320,
      height: 320,
    }
  )
  const emits = defineEmits<{
    (e: 'update:modelValue', path: string): void
  }>()

  const uploadImageRef = ref<UploadInstance>()
  const headers = ref({ Authorization: `Bearer ${getToken()}` })
  const imageUrl = ref('')
  const uploading = ref(false)
  const uploadUrl = computed(() => import.meta.env.VITE_APP_BASE_API + props.upload)
  const iconClass = computed(() => (uploading.value ? 'i-ep-loading' : 'i-ep-plus'))
  const iconStyle = computed<CSSProperties>(() => {
    const w = props.width > 700 ? 350 : 150
    const h = (w * props.height) / props.width

    return { height: `${h}px`, width: `${w}px`, lineHeight: `${h}px`, textAlign: 'center' }
  })

  watch(
    () => props.preview,
    (newV) => {
      // console.log('Former-log UploadImage watch [preview] newV: ' + newV + ', oldV: ' + oldV)
      imageUrl.value = props.isCreate ? '' : (newV ?? '')
    },
    {
      immediate: true,
    }
  )

  const handleOnProgress: UploadProps['onProgress'] = () => {
    uploading.value = true
  }
  const handleError: UploadProps['onError'] = (err: any) => {
    err = JSON.parse(err.message)
    ElMessage({ message: err.errors[props.field][0], type: 'error' })
    uploading.value = false
  }
  const handleSuccess: UploadProps['onSuccess'] = (res) => {
    uploading.value = false
    imageUrl.value = res.data.url

    // this.imageUrl = URL.createObjectURL(file.raw)
    // console.log('Upload Image handleSuccess: ', res.data.file_path)
    // console.log('UploadImage-props res:', res)

    emits('update:modelValue', res.data.file_path)
  }

  const beforeUpload: UploadProps['beforeUpload'] = (file) => {
    imageUrl.value = ''

    const imgTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif']
    const isLimit = file.size / 1024 / 1024 < 4

    if (!isLimit) {
      ElMessage({ message: '上传图片大小不能超过 4MB', type: 'error' })
      imageUrl.value = props.preview === '' ? '' : props.preview
      return false
    }

    // if (imgTypes.indexOf(file.raw.type) === -1) {
    if (!imgTypes.includes(file.type)) {
      ElMessage({ message: '仅支持 jpg、jpeg、png 及 gif 格式', type: 'error' })
      imageUrl.value = props.preview === '' ? '' : props.preview
      return false
    }

    return true
  }

  const resetData = () => {
    uploadImageRef.value?.clearFiles()
    imageUrl.value = ''
  }

  defineExpose({
    resetData,
  })
</script>

<style lang="scss" scoped>
  .image-uploader {
    margin-bottom: 1px;
    line-height: 0;
    border: 1px dashed var(--border-input);
    border-radius: 6px;

    &:hover {
      border-color: var(--primary-color);

      .color-info {
        color: var(--primary-color);
      }
    }
  }

  .image-preview {
    display: block;
    border-radius: 6px;
  }
</style>
